﻿using System;

namespace lab00
{
    interface IPrinter
    {
        void Print(string word);
        void Print(char sign);
    }

    class PrinterDefault : IPrinter
    {
        public virtual void Print(string word)
        {
            Console.Write(word);
        }

        public virtual void Print(char sign)
        {
            Console.Write(sign);
        }
    }

    class PrinterSpecial : PrinterDefault
    {
        public override void Print(string word)
        {
            Console.Write("(" + word + ")");
        }
    }

    interface IPrintable
    {
        void Print(IPrinter printer);
    }

    class Word : IPrintable
    {
        private readonly string _word;
        public Word(string word)
        {
            _word = word;
        }
        public virtual void Print(IPrinter printer)
        {
            printer.Print(_word);
        }
    }

    class Sign: IPrintable
    {
        private readonly char _sign;
        public Sign(char sign)
        {
            _sign = sign;
        }

        public virtual void Print(IPrinter printer)
        {
            printer.Print(_sign);
        }
    }

    class Text : IPrintable
    {
        private readonly IPrintable[] _printables;
        public Text(params IPrintable[] printables)
        {
            _printables = printables;
        }

        public virtual void Print(IPrinter printer)
        {
            foreach (IPrintable printable in _printables)
            {
                printable.Print(printer);
            }
        }
    }

    interface IPrinterDelegate : IPrinter
    {
        void Print2(IPrintable printable);
    }

    class PrinterDelegate : PrinterSpecial, IPrinterDelegate
    {
        public virtual void Print2(IPrintable printable)
        {
            printable.Print(this);
        }
    }


    class Program
    {
        static void Main()
        {
            Text txt = new Text(
                new Word("Testing"), new Sign(' '),
                new Word("my"), new Sign(' '),
                new Word("architecture"), new Sign('!'),
                new Sign('\n'));

            txt.Print(new PrinterDefault());
            txt.Print(new PrinterSpecial());

            PrinterDelegate printer = new PrinterDelegate();
            printer.Print2(txt);
        }
    }
}
